package com.cskaoyan.javase.exception._1handle._4throw;

/**
 * @description: 异常的抛出-throw关键字
 * @author: wuguidong@cskaoyan.onaliyun.com
 **/

/**
 * throws关键字仅仅在方法声明中表示异常抛出的可能性,而如果想要在方法体中,在代码中,明确的,一定的抛出一个异常对象,就需要使用throw关键字
 *
 * throw关键字用于方法体中,用于明确的抛出一个异常对象
 * 语法:
 *      throw 异常对象
 * 异常对象怎么来?
 *      new关键字,使用构造器创建对象
 *      所有的异常类都具有两个构造方法:
 *          1.无参的
 *          2.带String参数的
 *      其中无参的创建出来的异常对象不带任何说明信息,String就带了说明信息
 *
 * throw关键字的使用:
 *      1.throw+运行时异常对象,表示在方法中明确抛出一个运行时异常对象
 *          而运行时异常只要不try...catch,默认就会往上抛出
 *          所以这时不需要其它操作,该运行时异常对象,就会被抛给方法的调用者
 *          注意不要在使用throw时,再去捕获异常了
 *
 *      2.throw+编译时异常对象,表示在方法中明确抛出一个编译时异常
 *          这时,该行代码就会报错,因为编译时需要显式处理
 *          建议配合throws关键字将编译时异常抛出去
 *
 * 注意事项:
 *      1.throw表示明确抛出某一个对象,所以它的后面只能跟一个对象.
 *      2.throw+编译时异常,需要明确的处理它,当然最好配合throws抛出去
 *      3.throw+异常对象抛给方法的调用者后,后面的代码都不能执行了,当然它的后面也无法写代码
 *          在很多时候,如果不知道方法的返回值应该写什么,可以用抛出异常来代替return 返回值.
 *
 *
 */
public class Demo {
    public static void main(String[] args) {
        /*System.out.println("before");
        //test();
        try {
            test2();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        System.out.println("after");*/

        int[] arr = {1, 2, 3, 4, 5};
        arr = null;
        try {
            System.out.println(getMax(arr));
        } catch (IllegalArgumentException e) {
            //向用户传递数据,提示用户修改
            e.printStackTrace();
        }
        System.out.println("after");
    }

    public static void test() {
        //在这里抛出一个运行时异常对象,空指针异常
        /*NullPointerException npe = new NullPointerException("你是被抛出的空指针异常对象");
        throw  npe;*/
        throw new NullPointerException("你是被抛出的空指针异常对象");
        //Unreachable statement
        //System.out.println();
    }

    public static void test2() throws CloneNotSupportedException {
        //抛出一个编译时异常
        throw new CloneNotSupportedException("你是被抛出的编译时异常");
        //System.out.println();
    }

    //求数组元素的最大值
    public static int getMax(int[] arr) {
        //考虑传入数组的长度为0或者是null
        /**
         * 1.考虑用包装类作为返回值
         * 2.抛出异常
         */
        if (arr == null || arr.length == 0) throw new IllegalArgumentException("数组为空或者是null!");


        int max = arr[0];
        for (int element : arr) {
            if (element > max) max = element;
        }
        return max;
    }
}
